<?php

/**
 * localized : Extends the multiple class in order to make an internationalizable class
 *
 * @package
 * @author Alexis Eric
 * @copyright Copyright (c) 2012 - Erra Prod
 * @version $1.0$
 * @access public
 */
class Erra_Fields_Base_Localized extends Erra_Fields_Base_Multiple {

    protected $_isLocalized = false;
    protected $_localizedInstances = array();
    
    public function __construct($objectId = null) {
        parent::__construct($objectId);
    }
    /**
     * localized::isLocalized() : Checks if the field is loaclized
     *
     * @return : TRUE if field is localized, else, it returns false
     */
    public function isLocalized() {
        return $this->_isLocalized;
    }

    /**
     * localized::_localize() : Internationalizes a field
     *
     * @return Erra_Fields_Base_Field
     */
    public function _localize() {
        $this->setLocalizeFlag();
        $langs = array_keys(Erra_Core_Locale::getAvailableLangs());

        $safeCopy = Erra_Fields_Base_Field::cloneField($this);

        foreach ($langs as $language) {
            $this->_localizedInstances[$language] = Erra_Fields_Base_Field::cloneField($safeCopy);
        }
        // Clean instances and subfields
        $this->_subFields = array();
        $this->instances = array();

        return $this;
    }

    /**
     * localized::containsLocalizable() : Check if data are internationalizable
     *
     * @param mixed $atDirectChild : This parameters affine the search to add proximity. eg :
     * $paragraphe = new Erra_Fields_Base_Field('paragraphe'); $titre = new Erra_Fields_Texte('titre'); $titre->_localize(); $paragraphe->addField($titre);
     * With $atDirectChild=FALSE (default), the function will return TRUE on $paragraphe and TRUE on $titre.
     * With $atDirectChild=TRUE, the function will retunr FALSE on $paragraphe and TRUE on $titre;
     * @return - TRUE if field contains localized data, else it will return false
     */
    public function containsLocalizable($atDirectChild = false) {
        if (count($this->_localizedInstances) > 0 && $atDirectChild == true) {
            return true;
        }

        if ($this->_containsLocalizable()) {
            if ($atDirectChild == false)
                return true;
        }
        return false;
    }

    /**
     * localized::_containsLocalizable() : Internal searching function for containsLocalizable()
     *
     * @return
     */
    public function _containsLocalizable() {
        if ($this->isLocalized())
            return true;

        for ($i = 0; $i < count($this->instances); $i++) {
            if ($this->instances[$i]->containsLocalizable())
                return true;
        }
        foreach ($this->_subFields as $aSubField) {
            if ($aSubField->containsLocalizable())
                return true;
        }
        return false;
    }

    /**
     * localized::setLocalized() - Setter for the $isLocalized parameter
     *
     * @param mixed $value - Boolean to check if field is localized or not
     * @return
     */
    public function setLocalized($value) {
        $this->_isLocalized = $value;
        return $this;
    }

    /**
     * localized::setLocalizeFlag() - Internal construction fonction to mark fields as localized
     *
     * @return
     */
    public function setLocalizeFlag() {
        $this->_isLocalized = true;
        for ($i = 0; $i < count($this->instances); $i++) {
            $this->instances[$i]->setLocalizeFlag();
        }
        foreach ($this->_subFields as $aSubFieldKey => $aSubField) {
            $this->_subFields[$aSubFieldKey]->setLocalizeFlag();
        }
        return $this;
    }

    /**
     * localized::fillLocalizedFields() : Fills a field with localized data
     *
     * @param mixed $data_array - An associative array which contains data for localized field (an array with country codes as keys)
     * @return
     */
    public function fillLocalizedFields($data_array) {
        foreach ($this->_localizedInstances as $keyLang => $aLocalizedInstance) {

            if (isset($data_array[$keyLang])) {
                $newData = Erra_Serialization_SerializerJson::unserializeRaw($data_array[$keyLang]);
                $aLocalizedInstance->setRawData($newData);
            }
        }
        return $this;
    }

    /**
     * localized::isLocalKey() : Check if a key is a country code
     *
     * @param mixed $string - La chaine de caractère Ã  analyser
     * @return boolean
     */
    public static function isLocalKey($string) {
        /* FIXME : a country key can be orphan if the user reduces the language count : this function should search on all keys ? */
        //$langs = array_keys(Erra_Core_Locale::getAvailableLangs());
        $langs = array_keys(Erra_Core_Locale::getCodesEn());
        foreach ($langs as $language) {
            if ((string) $language == $string)
                return true;
        }
        return false;
    }

    /**
     * localized::rawDataContainsLang() : Checks if an associative array contains language data
     *
     * @param mixed $rawData - The associative array to check
     * @return boolean
     */
    public static function rawDataContainsLang($rawData) {
        //$langs = array_keys(Erra_Core_Locale::getAvailableLangs());
        $langs = array_keys(Erra_Core_Locale::getCodesEn());

        if (is_array($rawData)) {
            $rawDataKeys = array_keys($rawData);
            foreach ($langs as $language) {
                foreach ($rawDataKeys as $rawDataKey) {
                    if ($language === $rawDataKey) {
                        return true;
                    }
                }
            }
        } else if (is_string($rawData)) {
            foreach ($langs as $language) {
                $comparison = '___' . (string) $language;
                if (strstr($rawData, $comparison) !== FALSE) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * localized::getLocalizedInstanceAt() - Returns the localized version (fr, en, etc...) of a localized field
     *
     * @param mixed $language - The field language you want to get
     * @return Erra_Fields_Base_Field
     */
    public function getLocalizedInstanceAt($language) {
        return (isset($this->_localizedInstances[$language])) ? $this->_localizedInstances[$language] : null;
    }

    /**
     * localized::getAll_localizedInstances() - Get all localized instances of the field
     *
     * @return Array
     */
    public function getAll_localizedInstances() {
        return $this->_localizedInstances;
    }

    /**
     * localized::langArrayNaturalOrder() : Sort a language array and place $targetLang at index 0
     *
     * @param mixed $input - The language array you wish to order
     * @param mixed $targetLang - The language code which should start the array
     * @return Array
     */
    public static function langArrayNaturalOrder($input, $targetLang) {
        $result = array();
        $count = 0;
        $result[0] = $targetLang;
        foreach ($input as $langKey => $langValue) {
            if ($langKey != $targetLang)
                $result[] = $langKey;
        }
        return $result;
    }

}

?>